
You can use the programs in this folder to prove that
system calls are 10 times slower than function calls.
This explains why buffering is so useful (it cuts down on
the number of system calls needed to do an I/O operation).


Use the command in wget-big-text-file.cmd to download a fairly
large text file.

>wget-big-text-file.cmd

Use the commands in create-large-text-file.cmd to create a
text file that is about 50 MB.

>create-large-text-file.cmd

Compile countStdin-Win32.c and countStdin-CLib.c.

>C:\cs30200\MinGW32\bin\gcc.exe -o countStdin-Win32.exe  countStdin-Win32.c

>C:\cs30200\MinGW32\bin\gcc.exe -o countStdin-CLib.exe  countStdin-CLib.c

Run

>timethis countStdin-Win32.exe < big.txt

>timethis countStdin-CLib.exe < big.txt

Both programs use a buffer size of 1, but the
C library version runs at least 10 times faster
than the Windows library version. Why?

The C library function fread() does its own buffering.
So even though the buffer size seems to be only 1, in
fact there is a reasonable size user space buffer
within fread().

In the file countStdin-CLib.c, un-comment the line
that calls setvbuf(). This function call disables
the buffer within fread(). Now the C library function
fread() in countStdin-CLib.c acts just like the Windows
function ReadFile() in countStdin-Win32.c (or the Linux
function read() in countStdin-Posix.c), neither has any
user space buffering.

Run again
>timethis countStdin-CLib.exe < big.txt

The time should be almost the same as
>timethis countStdin-Win32.exe < big.txt


Here is what this experiment shows. The program
countStdin-CLib.c, with the C library buffering
turned on, makes 50 million function calls to fread()
(but very few NTReadFile system calls) in about 3 seconds.

The program countStdin-CLib.c, with the C library
buffering turned off, and the program countStdin-Win32.c,
both make 50 million system calls to NTReadFile (because
their user space buffer has size 1) in about 30 seconds.

So a system call to NTReadFile is about 10 times slower that
a function call to fread() or ReadFile(). In general, 
system calls are at least 10 times slower than function calls.

NOTE: The setvbuf() function turns off user space buffering
      in the C library. There is no way to turn off disk
      buffering in the operating system kernel. The kernel
      always uses buffering for disk I/O. However, there are
      a few devices for which you can turn off kernel buffering
      (e.g., the console keyboard and the console screen).


You can do the exact same experiment on Linux by using
the two programs countStdin-CLib.c and countStdin-Posix.c.
